﻿#region Header
// Copyright 2007-2011, Jerónimo Milea
// 
// This file is part of NetJsWire.
// 
//     NetJsWire is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
// 
//     NetJsWire is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
// 
//     You should have received a copy of the GNU General Public License
//     along with NetJsWire.  If not, see <http://www.gnu.org/licenses/>.
#endregion

using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using NetJsWire.JsonRpcHandler;
using NetJsWire.Util;
using ToolBar = NetJsWire.Widgets.Ui.ToolBar.ToolBar;

namespace NetJsWire.Widgets.Config
{
    [TypeDescriptionProvider( typeof( ConfigOptionsPropertys ) )]
    public class PanelConfigOptions : ContainerConfigOptions
    {
        private bool _animCollapse = true;
        private string _autoLoad;
        private string _baseCls;
        private bool _bodyBorder = true;
        private string _bodyCfg;
        private string _bodyCssClass;
        private string _bodyStyle;
        private bool _border = true;
        private ToolBar _bottomBar;
        private string _bottomBarCfg;
        private ButtonAlign _buttonAlign = ButtonAlign.Right;
        private string _bwrapCfg;
        private bool _closable;
        private bool _collapseFirst = true;
        private bool _collapsed;
        private bool _collapsible;
        private bool _shadow;
        private List<ToolConfig> _tools = new List<ToolConfig>();
        private bool _unstyled;

        public PanelConfigOptions( IWidget ownerWidget )
            : base( ownerWidget )
        {
        }

        /// <summary>
        ///   true to animate the transition when the panel is collapsed, false to skip the animation (defaults to true if the Ext.Fx class is available, otherwise false).
        /// </summary>
        [Description( "true to animate the transition when the panel is collapsed, false to skip the animation (defaults to true if the Ext.Fx class is available, otherwise false)." )]
        [DefaultValue( true )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override bool AnimCollapse
        {
            get { return _animCollapse; }
            set
            {
                SetValue( "animCollapse", value, true, _animCollapse );
                _animCollapse = value;
            }
        }

        /// <summary>
        ///   true to use height:'auto', false to use fixed height (defaults to false).
        ///   <remarks>
        ///     Setting autoHeight: true means that the browser will manage the panel's height based on its contents, and that Ext will not manage it at all.
        ///     If the panel is within a layout that manages dimensions (fit, border, etc.) then setting autoHeight: true can cause issues with scrolling and 
        ///     will not generally work as expected since the panel will take on the height of its contents rather than the height required by the Ext layout.
        ///   </remarks>
        /// </summary>
        [Description( "true to use height:'auto', false to use fixed height (defaults to false)." )]
        [DefaultValue( false )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override bool AutoHeight
        {
            get { return base.AutoHeight; }
            set { base.AutoHeight = value; }
        }

        /// <summary>
        ///   A valid url spec according to the Updater Ext.Updater.update method.
        ///   If autoLoad is not null, the panel will attempt to load its contents immediately upon render.
        ///   The URL will become the default URL for this panel's body element, so it may be refreshed at any time.
        /// </summary>
        [Description( "A valid url spec according to the Updater Ext.Updater.update method." )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override string AutoLoad
        {
            get { return _autoLoad; }
            set
            {
                SetValue( "autoLoad", value, null, _autoLoad );
                _autoLoad = value;
            }
        }

        /// <summary>
        ///   The base CSS class to apply to this panel's element (defaults to 'x-panel').
        ///   Another option available by default is to specify 'x-plain' which strips all styling except for required attributes for Ext layouts to function (e.g. overflow:hidden). 
        ///   See <see cref = "Unstyled" /> also.
        /// </summary>
        [Description( "The base CSS class to apply to this panel's element (defaults to 'x-panel')." )]
        [DefaultValue( ( string ) null )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override string BaseCls
        {
            get { return _baseCls; }
            set
            {
                SetValue( "baseCls", value, null, _baseCls );
                _baseCls = value;
            }
        }

        /// <summary>
        ///   This can be a Ext.Toolbar object, a toolbar config, or an array of buttons/button configs to be added to the toolbar. Note that this is not available as a property after render.
        ///   To access the bottom toolbar after render, use getBottomToolbar.
        ///   <b>Note:</b> Although a Toolbar may contain Field components, these will not be updated by a load of an ancestor FormPanel. A Panel's toolbars are not part of the standard 
        ///   Container->Component hierarchy, and so are not scanned to collect form items. However, the values will be submitted because form submission parameters are collected from the DOM tree.
        /// </summary>
        [Description( "The bottom toolbar of the panel." )]
        [DefaultValue( null )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override ToolBar BottomBar
        {
            get { return _bottomBar; }
            set
            {
                SetValue( "bbar", value, null, _bottomBar );
                _bottomBar = value;
                if ( _bottomBar != null )
                {
                    _bottomBar.IsInPanel = true;
                    _bottomBar.Dock = DockStyle.Bottom;
                }
            }
        }

        /// <summary>
        ///   A DomHelper element specification object specifying the element structure of this Panel's bbar Element. See <see cref = "BodyCfg" /> also.
        /// </summary>
        [Description( "A DomHelper element specification object specifying the element structure of this Panel's bbar Element." )]
        [DefaultValue( ( string ) null )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override string BottomBarCfg
        {
            get { return _bottomBarCfg; }
            set
            {
                SetValue( "bbarCfg", value, null, _bottomBarCfg );
                _bottomBarCfg = value;
            }
        }

        /// <summary>
        ///   True to display an interior border on the body element of the panel, false to hide it (defaults to true).
        ///   <remarks>
        ///     This only applies when border == true. If border == true and bodyBorder == false, the border will display as a 1px wide inset border, giving the entire body element an inset appearance.
        ///   </remarks>
        /// </summary>
        [Description( "True to display an interior border on the body element of the panel, false to hide it (defaults to true)." )]
        [DefaultValue( true )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override bool BodyBorder
        {
            get { return _bodyBorder; }
            set
            {
                SetValue( "bodyBorder", value, true, _bodyBorder );
                _bodyBorder = value;
            }
        }

        /// <summary>
        ///   A DomHelper element specification object may be specified for any Panel Element.
        ///   By default, the Default element in the table below will be used for the html markup to create a child element with the commensurate Default class name (<see cref = "BaseCls" /> will be replaced by <see cref = "BaseCls" />):
        /// </summary>
        /// <remarks>
        ///   <table>
        ///     <theader>
        ///       <tr>
        ///         <td>Panel Element</td>
        ///         <td>Default Element</td>
        ///         <td>Default class</td>
        ///         <td>Custom Element</td>
        ///         <td>Additional class</td>
        ///         <td>Additional style</td>
        ///       </tr>
        ///     </theader>
        ///     <tbody>
        ///       <tr>
        ///         <td>header</td>
        ///         <td>div</td>
        ///         <td>baseCls+'-header'</td>
        ///         <td>headerCfg</td>
        ///         <td>headerCssClass</td>
        ///         <td>headerStyle</td>
        ///       </tr>
        ///       <tr>
        ///         <td>header</td>
        ///         <td>div</td>
        ///         <td>baseCls+'-bwrap'</td>
        ///         <td>bwrapCfg</td>
        ///         <td>bwrapCssClass</td>
        ///         <td>bwrapStyle</td>
        ///       </tr>
        ///       <tr>
        ///         <td>+ tbar</td>
        ///         <td>div</td>
        ///         <td>baseCls+'-tbar'</td>
        ///         <td>tbarCfg</td>
        ///         <td>tbarCssClass</td>
        ///         <td>tbarStyle</td>
        ///       </tr>
        ///       <tr>
        ///         <td>+ body</td>
        ///         <td>div</td>
        ///         <td>baseCls+'-body'</td>
        ///         <td>bodyCfg</td>
        ///         <td>bodyCssClass</td>
        ///         <td>bodyStyle</td>
        ///       </tr>
        ///       <tr>
        ///         <td>+ bbar</td>
        ///         <td>div</td>
        ///         <td>baseCls+'-bbar'</td>
        ///         <td>bbarCfg</td>
        ///         <td>bbarCssClass</td>
        ///         <td>bbarStyle</td>
        ///       </tr>
        ///       <tr>
        ///         <td>+ footer</td>
        ///         <td>div</td>
        ///         <td>baseCls+'-footer'</td>
        ///         <td>footerCfg</td>
        ///         <td>footerCssClass</td>
        ///         <td>footerStyle</td>
        ///       </tr>
        ///     </tbody>
        ///   </table>
        ///   <example>
        ///     Configuring a Custom element may be used, for example, to force the body Element to use a different form of markup than is created by default.
        ///     An example of this might be to create a child Panel containing a custom content, such as a header, or forcing centering of all Panel content by having the body be a <center> element:
        ///                                                                                                                                                                            <code>
        ///                                                                                                                                                                              new Ext.Panel({
        ///                                                                                                                                                                              title: 'Message Title',
        ///                                                                                                                                                                              renderTo: Ext.getBody(),
        ///                                                                                                                                                                              width: 200, height: 130,
        ///                                                                                                                                                                              bodyCfg: {
        ///                                                                                                                                                                              tag: 'center',
        ///                                                                                                                                                                              cls: 'x-panel-body',  // Default class not applied if Custom element specified
        ///                                                                                                                                                                              html: 'Message'
        ///                                                                                                                                                                              },
        ///                                                                                                                                                                              footerCfg: {
        ///                                                                                                                                                                              tag: 'h2',
        ///                                                                                                                                                                              cls: 'x-panel-footer'        // same as the Default class
        ///                                                                                                                                                                              html: 'footer html'
        ///                                                                                                                                                                              },
        ///                                                                                                                                                                              footerCssClass: 'custom-footer', // additional css class, see addClass
        ///                                                                                                                                                                              footerStyle:    'background-color:red' // see bodyStyle
        ///                                                                                                                                                                              });
        ///                                                                                                                                                                            </code>
        ///                                                                                                                                                                            The example above also explicitly creates a footer with custom markup and styling applied.
        ///   </example>
        /// </remarks>
        [Description( "A DomHelper element specification object may be specified for any Panel Element." )]
        [DefaultValue( ( string ) null )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override string BodyCfg
        {
            get { return _bodyCfg; }
            set
            {
                SetValue( "bodyCfg", value, null, _bodyCfg );
                _bodyCfg = value;
            }
        }

        /// <summary>
        ///   Additional css class selector to be applied to the body element in the format expected by <c>Ext.Element.addClass</c> (defaults to null). See <see cref = "BodyCfg" />.
        /// </summary>
        [Description( "Additional css class selector to be applied to the body element in the format expected by Ext.Element.addClass (defaults to null)." )]
        [DefaultValue( ( string ) null )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override string BodyCssClass
        {
            get { return _bodyCssClass; }
            set
            {
                SetValue( "bodyCssClass", value, null, _bodyCssClass );
                _bodyCssClass = value;
            }
        }

        /// <summary>
        ///   Custom CSS styles to be applied to the body element in the format expected by <c>Ext.Element.applyStyles</c> (defaults to null). See <see cref = "BodyCfg" />.
        /// </summary>
        [Description( "Custom CSS styles to be applied to the body element in the format expected by Ext.Element.applyStyles (defaults to null)." )]
        [DefaultValue( ( string ) null )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override string BodyStyle
        {
            get { return _bodyStyle; }
            set
            {
                SetValue( "bodyStyle", value, null, _bodyStyle );
                _bodyStyle = value;
            }
        }

        /// <summary>
        ///   True to display the borders of the panel's body element, false to hide them (defaults to true).
        ///   By default, the border is a 2px wide inset border, but this can be further altered by setting <see cref = "BodyBorder" /> to false.
        /// </summary>
        [Description( "True to display the borders of the panel's body element, false to hide them (defaults to true)." )]
        [DefaultValue( true )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override bool Border
        {
            get { return _border; }
            set
            {
                SetValue( "border", value, true, _border );
                _border = value;
            }
        }

        /// <summary>
        ///   The alignment of any buttons added to this panel.
        /// </summary>
        [Description( "The alignment of any buttons added to this panel." )]
        [DefaultValue( ButtonAlign.Right )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override ButtonAlign ButtonAlign
        {
            get { return _buttonAlign; }
            set
            {
                SetValue( "buttonAlign", value, ButtonAlign.Right, _buttonAlign );
                _buttonAlign = value;
            }
        }

        /// <summary>
        ///   A DomHelper element specification object specifying the element structure of this Panel's bwrap Element. See <see cref = "BodyCfg" /> also.
        /// </summary>
        [Description( "A DomHelper element specification object specifying the element structure of this Panel's bwrap Element." )]
        [DefaultValue( ( string ) null )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override string BwrapCfg
        {
            get { return _bwrapCfg; }
            set
            {
                SetValue( "bwrapCfg", value, null, _bwrapCfg );
                _bwrapCfg = value;
            }
        }

        /// <summary>
        ///   Panels themselves do not directly support being closed, but some Panel subclasses do (like Ext.Window) or a Panel Class within an Ext.TabPanel. Specify true to enable closing in such situations. Defaults to false.
        /// </summary>
        [Description( "Panels themselves do not directly support being closed, but some Panel subclasses do (like Ext.Window) or a Panel Class within an Ext.TabPanel. Specify true to enable closing in such situations. Defaults to false." )]
        [DefaultValue( false )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override bool Closable
        {
            get { return _closable; }
            set
            {
                SetValue( "closable", value, false, _closable );
                _closable = value;
            }
        }

        /// <summary>
        ///   true to make sure the collapse/expand toggle button always renders first (to the left of) any other tools in the panel's title bar, false to render it last (defaults to true).
        /// </summary>
        [Description( "true to make sure the collapse/expand toggle button always renders first (to the left of) any other tools in the panel's title bar, false to render it last (defaults to true)." )]
        [DefaultValue( true )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override bool CollapseFirst
        {
            get { return _collapseFirst; }
            set
            {
                SetValue( "collapseFirst", value, true, _collapseFirst );
                _collapseFirst = value;
            }
        }

        /// <summary>
        ///   true to render the panel collapsed, false to render it expanded (defaults to false).
        /// </summary>
        [Description( "true to render the panel collapsed, false to render it expanded (defaults to false)." )]
        [DefaultValue( false )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override bool Collapsed
        {
            get { return _collapsed; }
            set
            {
                SetValue( "collapsed", value, false, _collapsed );
                _collapsed = value;
            }
        }

        /// <summary>
        ///   True to make the panel collapsible and have the expand/collapse toggle button automatically rendered into the header tool button area, false to keep the panel statically sized with no button (defaults to false).
        /// </summary>
        [Description( "True to make the panel collapsible and have the expand/collapse toggle button automatically rendered into the header tool button area, false to keep the panel statically sized with no button (defaults to false)." )]
        [DefaultValue( false )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override bool Collapsible
        {
            get { return _collapsible; }
            set
            {
                SetValue( "collapsible", value, false, _collapsible );
                _collapsible = value;
            }
        }

        /// <summary>
        ///   Overrides the <see cref = "BaseCls" /> setting to <see cref = "BaseCls" /><c> = 'x-plain'</c> which renders the panel unstyled except for required attributes for Ext layouts to function (e.g. <c>overflow:hidden</c>).
        /// </summary>
        [Description( "Overrides the baseCls setting to baseCls = 'x-plain' which renders the panel unstyled except for required attributes for Ext layouts to function (e.g. overflow:hidden)." )]
        [DefaultValue( false )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override bool Unstyled
        {
            get { return _unstyled; }
            set
            {
                SetValue( "unstyled", value, false, _unstyled );
                _unstyled = value;
            }
        }

        /// <summary>
        ///   True to display a shadow around this panel.
        /// </summary>
        [Description( "true to display a shadow around this panel" )]
        [DefaultValue( false )]
        [Browsable( true ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public override bool Shadow
        {
            get
            {
                return _shadow;
            }
            set
            {
                SetValue( "shadow", value, false, _shadow );
                _shadow = value;
            }
        }

        /// <summary>
        ///   An array of tool button configs to be added to the header tool area. When rendered, each tool is stored as an Element referenced by a public property called tools.&lt;tool-type&gt;.
        /// </summary>
        [Browsable( true )]
        //[DefaultValue( typeof( List<ToolConfig> ), "" )]
        [Description( "An array of tool button configs to be added to the header tool area. When rendered, each tool is stored as an Element referenced by a public property called tools.&lt;tool-type&gt;.\nYou can use {0} in Handler to refer to the owner component of the tool and {1} for the parent container." )]
        [DesignerSerializationVisibility( DesignerSerializationVisibility.Content )]
        public override List<ToolConfig> Tools
        {
            get { return _tools; }
            set { _tools = value; }
        }

        public bool ShouldSerializeTools()
        {
            return Tools != null && Tools.Count > 0;
        }
    }
}